home *** CD-ROM | disk | FTP | other *** search
/ Java Programmer's Toolkit / Java Programmer's Toolkit.iso / solaris2 / jdk / src / java / awt / polygon.jav < prev    next >
Encoding:
Text File  |  1995-10-30  |  5.0 KB  |  182 lines

  1. /*
  2.  * @(#)Polygon.java    1.6 95/10/05 Sami Shaio
  3.  *
  4.  * Copyright (c) 1995 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software
  7.  * and its documentation for NON-COMMERCIAL purposes and without
  8.  * fee is hereby granted provided that this copyright notice
  9.  * appears in all copies. Please refer to the file "copyright.html"
  10.  * for further important copyright and licensing information.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  13.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  14.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  15.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  16.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  17.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  18.  */
  19. package java.awt;
  20.  
  21. /**
  22.  * A polygon consists of a list of x and y coordinates.
  23.  *
  24.  * @version     1.6, 10/05/95
  25.  * @author     Sami Shaio
  26.  * @author      Herb Jellinek
  27.  */
  28. public class Polygon {
  29.     /**
  30.      * The total number of points.
  31.      */
  32.     public int npoints = 0;
  33.  
  34.     /**
  35.      * The array of x coordinates.
  36.      */
  37.     public int xpoints[] = new int[4];
  38.  
  39.     /**
  40.      * The array of y coordinates.
  41.      */
  42.     public int ypoints[] = new int[4];
  43.     
  44.     /*
  45.      * Bounds of the polygon.
  46.      */
  47.     Rectangle bounds = null;
  48.     
  49.     /**
  50.      * Creates an empty polygon.
  51.      */
  52.     public Polygon() {
  53.     }
  54.  
  55.     /**
  56.      * Constructs and initializes a Polygon from the specified parameters.
  57.      * @param xpoints the array of x coordinates
  58.      * @param ypoints the array of y coordinates
  59.      * @param npoints the total number of points in the Polygon
  60.      */
  61.     public Polygon(int xpoints[], int ypoints[], int npoints) {
  62.     this.npoints = npoints;
  63.     this.xpoints = new int[npoints];
  64.     this.ypoints = new int[npoints];
  65.     System.arraycopy(xpoints, 0, this.xpoints, 0, npoints);
  66.     System.arraycopy(ypoints, 0, this.ypoints, 0, npoints);    
  67.     }
  68.     
  69.     /*
  70.      * Calculate the bounding box of the points passed to the constructor.
  71.      * Sets 'bounds' to the result.
  72.      */
  73.     void calculateBounds(int xpoints[], int ypoints[], int npoints) {
  74.     int boundsMinX = Integer.MAX_VALUE;
  75.     int boundsMinY = Integer.MAX_VALUE;
  76.     int boundsMaxX = Integer.MIN_VALUE;
  77.     int boundsMaxY = Integer.MIN_VALUE;
  78.     
  79.     for (int i = 0; i < npoints; i++) {
  80.         int x = xpoints[i];
  81.         boundsMinX = Math.min(boundsMinX, x);
  82.         boundsMaxX = Math.max(boundsMaxX, x);
  83.         int y = ypoints[i];
  84.         boundsMinY = Math.min(boundsMinY, y);
  85.         boundsMaxY = Math.max(boundsMaxY, y);
  86.     }
  87.     bounds = new Rectangle(boundsMinX, boundsMinY,
  88.                    boundsMaxX - boundsMinX,
  89.                    boundsMaxY - boundsMinY);
  90.     }
  91.  
  92.     /*
  93.      * Update the bounding box to fit the point x, y.
  94.      */
  95.     void updateBounds(int x, int y) {
  96.     bounds.x = Math.min(bounds.x, x);
  97.     bounds.width = Math.max(bounds.width, x - bounds.x);
  98.     bounds.y = Math.min(bounds.y, y);
  99.     bounds.height = Math.max(bounds.height, y - bounds.y);
  100.     }    
  101.  
  102.     /**
  103.      * Appends a point to a polygon.  If inside(x, y) or other operation
  104.      * that calculates the bounding box has already been performed, this
  105.      * updates the bounds accordingly.
  106.      * @param x the x coordinate of the point
  107.      * @param y the y coordinate of the point
  108.      */
  109.     public void addPoint(int x, int y) {
  110.     if (npoints == xpoints.length) {
  111.         int tmp[];
  112.  
  113.         tmp = new int[npoints * 2];
  114.         System.arraycopy(xpoints, 0, tmp, 0, npoints);
  115.         xpoints = tmp;
  116.  
  117.         tmp = new int[npoints * 2];
  118.         System.arraycopy(ypoints, 0, tmp, 0, npoints);
  119.         ypoints = tmp;
  120.     }
  121.     xpoints[npoints] = x;
  122.     ypoints[npoints] = y;
  123.     npoints++;
  124.     if (bounds != null) {
  125.         updateBounds(x, y);
  126.     }
  127.     }
  128.  
  129.     /**
  130.      * getBoundingBox() - what area does this polygon span?
  131.      * @return a Rectangle defining the bounds of the Polygon.
  132.      */
  133.     public Rectangle getBoundingBox() {
  134.     if (bounds == null) {
  135.         calculateBounds(xpoints, ypoints, npoints);
  136.     }
  137.     return bounds;
  138.     }
  139.     
  140.     /**
  141.      * Is point (x, y) inside the polygon?  Uses even-odd winding.
  142.      * @param x the X coordinate of the point to be tested
  143.      * @param y the Y coordinate of the point to be tested
  144.      *
  145.      * Based on code by Hanpeter van Vliet <hvvliet@inter.nl.net>.
  146.      */
  147.     public boolean inside(int x, int y) {
  148.     if (getBoundingBox().inside(x, y)) {
  149.         int hits = 0;
  150.         
  151.         // Walk the edges of the polygon
  152.         for (int i = 0; i < npoints; i++) {
  153.         int j = (i + 1) % npoints;
  154.         
  155.         int dx = xpoints[j] - xpoints[i];
  156.         int dy = ypoints[j] - ypoints[i];
  157.         
  158.         // ignore horizontal edges completely
  159.         if (dy != 0) {
  160.             // Check to see if the edge intersects
  161.             // the horizontal halfline through (x, y)
  162.             int rx = x - xpoints[i];
  163.             int ry = y - ypoints[i];
  164.             
  165.             // Quick and dirty way to deal with vertices
  166.             // that fall exactly on the halfline
  167.             if (ypoints[i] == y) ry--;
  168.             if (ypoints[j] == y) dy++;
  169.             
  170.             float s = (float)ry / (float)dy;
  171.             if (s >= 0.0 && s <= 1.0) {
  172.             if ((int)(s * dx) > rx) hits++;
  173.             }
  174.         }
  175.         }
  176.         
  177.         return (hits % 2) != 0;
  178.     }
  179.     return false;
  180.     }
  181. }
  182.